package org.apogee.mil.client.main.pages.admin.forms.group;

import java.util.ArrayList;

import org.apogee.mil.client.factories.ServerServiceFactory;
import org.apogee.mil.client.main.pages.admin.forms.widgets.GroupTest;
import org.apogee.mil.client.main.pages.admin.forms.widgets.GroupUser;
import org.apogee.mil.client.main.pages.admin.forms.widgets.Groups;
import org.apogee.mil.client.utils.Session;
import org.apogee.mil.shared.User;
import org.apogee.mil.shared.Constants.DisplayFormat;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.Record;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.HorizontalPanel;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Widget;

public class GroupConfigurationComponent implements IsWidget {

	private User currentUser;
	private Groups groups;
	private GroupTest groupTest;
	private GroupUser groupUser;
	private String selectedGroup = null;
	private HorizontalPanel hp;

	public GroupConfigurationComponent() {
		this.currentUser = ServerServiceFactory.getUser(Session.getSessionId());
		groups = new Groups(this);
		groupTest = new GroupTest();
		groupUser = new GroupUser();
	}

	@Override
	public Widget asWidget() {
		final ContentPanel cp = new ContentPanel();
		cp.setHeading("Group Configuration Selection");
		cp.setWidth(825);
		cp.setHeight(425);

		hp = new HorizontalPanel();

		hp.add(groups.asWidget());
		hp.add(groupTest.asWidget());
		hp.add(groupUser.asWidget());

		cp.add(hp);
		cp.setButtonAlign(HorizontalAlignment.CENTER);
		cp.addButton(new Button("Reset", new SelectionListener<ButtonEvent>() {  

			@Override  
			public void componentSelected(ButtonEvent ce) {  
				groupTest.getStore().rejectChanges();
				groupUser.getStore().rejectChanges();

			}  
		}));  

		cp.addButton(new Button("Save", new SelectionListener<ButtonEvent>() {  

			@Override  
			public void componentSelected(ButtonEvent ce) {
				
				ArrayList<BaseModel> changes = new ArrayList<BaseModel>();
				
				ArrayList<Record> testChanges = (ArrayList<Record>) groupTest.getStore().getModifiedRecords();
				ArrayList<Record> userChanges = (ArrayList<Record>) groupUser.getStore().getModifiedRecords();
				
				for(Record r : testChanges) {
					BaseModel bm = new BaseModel();
					bm.set(DisplayFormat.TEST_CHANGES, DisplayFormat.TEST_CHANGES);
					for (String s : r.getPropertyNames()) {
						bm.set(s, r.get(s));
					}
					changes.add(bm);
					if (bm.get(DisplayFormat.DELETE) != null && bm.get(DisplayFormat.DELETE).toString().toLowerCase().equals("true")) {
						groupTest.getStore().remove((BaseModel) r.getModel());
					}
				}
				
				
				for(Record r : userChanges) {
					BaseModel bm = new BaseModel();
					bm.set(DisplayFormat.USER_CHANGES, DisplayFormat.USER_CHANGES);
					for (String s : r.getPropertyNames()) {
						bm.set(s, r.get(s));
					}
					if (bm.get(DisplayFormat.DELETE) != null && bm.get(DisplayFormat.DELETE).toString().toLowerCase().equals("true")) {
						groupUser.getStore().remove((BaseModel) r.getModel());
					}
					changes.add(bm);
				}
				
				
				ServerServiceFactory.getAdminService(currentUser.getSessionId()).updateGroupings(selectedGroup, changes, new AsyncCallback<Boolean>() {
					
					@Override
					public void onSuccess(Boolean result) {
						if (result == false) {
							MessageBox.alert("Error", "Unable to update groupings", null);
							groupTest.getStore().rejectChanges();
							groupUser.getStore().rejectChanges();
							return;
						}
						Info.display("Success", "Groupings updated successfully");
						groupTest.getStore().commitChanges();
						groupUser.getStore().commitChanges();
						
					}
					
					@Override
					public void onFailure(Throwable caught) {
						MessageBox.alert("Error", "Unable to update groupings\n" + caught.getMessage(), null);
						groupTest.getStore().rejectChanges();
						groupUser.getStore().rejectChanges();
					}
				});
			}  
		}));

		return cp;
	}


	public void update(final String groupId) {
		selectedGroup = groupId;

		ServerServiceFactory.getAdminService(currentUser.getSessionId()).getTestsFromGroup(groupId, new AsyncCallback<ArrayList<BaseModel>>() {

			@Override
			public void onSuccess(ArrayList<BaseModel> result) {
				groupTest.getStore().removeAll();
				if (result.size() == 0) {
					MessageBox.info("Info", "No Tests Were Found for Group " + groupId, null);
					return;
				}
				
				groupTest.getStore().add(result);
				groupTest.enableAddButton();

			}

			@Override
			public void onFailure(Throwable caught) {
				MessageBox.alert("Error", "An Exception was thrown: " + caught.getMessage(), null);
				return;

			}
		});

		ServerServiceFactory.getAdminService(currentUser.getSessionId()).getUsersFromGroup(groupId, new AsyncCallback<ArrayList<BaseModel>>() {

			@Override
			public void onSuccess(ArrayList<BaseModel> result) {
				groupUser.getStore().removeAll();
				if (result.size() == 0) {
					MessageBox.info("Info", "No Users Were Found for Group " + groupId, null);
					return;
				}
				
				groupUser.getStore().add(result);
				groupUser.enableAddButton();

			}

			@Override
			public void onFailure(Throwable caught) {
				MessageBox.alert("Error", "An Exception was thrown: " + caught.getMessage(), null);
				return;

			}
		});

	}

}
